using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Web;
using System.Collections;
using System.Web.UI.WebControls;
using ICSharpCode.SharpZipLib.Zip;
using BbqFramework.Security;

namespace Bbq.Gallery
{
    public class PhysicalStorageGalleryProvider : GalleryProvider
    {
        private static GalleryAlbumNode _root = null;
        private static bool _isDirty = true;
        private static object rootLock = new object();
        /// <summary>
        /// Gets the root.
        /// </summary>
        /// <value>The root.</value>
        public override GalleryAlbumNode Root
        {
            get 
            {
                if (_isDirty || _root == null)
                {
                    lock (rootLock)
                    {
                        ScanDirectoryTree();
                        _isDirty = false;
                    }
                }
                return _root;
            }
        }

        /// <summary>
        /// Scans the directory tree.
        /// </summary>
        private void ScanDirectoryTree()
        {
            _root = new GalleryAlbumNode();
            GalleryAlbum rootAlbum = new GalleryAlbum();
            _root.Album = rootAlbum;
            ScanDirectoryHierarchy(_root);
            _root.Album = null;
        }

        /// <summary>
        /// Gets the album directory.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        protected DirectoryInfo GetAlbumDirectory(GalleryAlbum album)
        {
            return new DirectoryInfo(GalleryHelper.GetPhysicalPath(album.PathFromRoot));
        }

        /// <summary>
        /// Gets the album path.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override GalleryAlbum[] GetPathToAlbum(GalleryAlbum album)
        {
            GalleryAlbum current = album;
            List<GalleryAlbum> list = new List<GalleryAlbum>();
            ///if (!GalleryHelper.IsRootAlbum(album))
            {
                do
                {
                    list.Insert(0, current);
                    int pos = current.PathFromRoot.LastIndexOf(Path.DirectorySeparatorChar);
					if (pos > 0)
						current = this.GetGalleryAlbumInfo(current.PathFromRoot.Substring(0, pos));
					else if (pos == 0)
						current = this.GetGalleryAlbumInfo(string.Empty);
					else break;
                } while (true);
            }
            return list.ToArray();
        }

        /// <summary>
        /// Scans the directory hierarchy.
        /// </summary>
        /// <param name="node">The node.</param>
        private void ScanDirectoryHierarchy(GalleryAlbumNode node)
        {
            GalleryAlbum[] childAlbums = this.GetChildAlbums(node.Album);
            if (childAlbums != null && childAlbums.Length > 0)
            {
                node.ChildAlbums = new List<GalleryAlbumNode>(childAlbums.Length);
                foreach (GalleryAlbum album in childAlbums)
                {
                    GalleryAlbumNode albumNode = new GalleryAlbumNode(album);
                    node.ChildAlbums.Add(albumNode);

                    ScanDirectoryHierarchy(albumNode);
                }
            }
        }

        /// <summary>
        /// Determines whether [is root album] [the specified album].
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns>
        /// 	<c>true</c> if [is root album] [the specified album]; otherwise, <c>false</c>.
        /// </returns>
        public override bool IsRootAlbum(GalleryAlbum album)
        {
            return string.IsNullOrEmpty(album.PathFromRoot);
        }

        /// <summary>
        /// Creates the album.
        /// </summary>
        /// <param name="album">The album.</param>
        public override bool CreateAlbum(GalleryAlbum parent, GalleryAlbum album)
        {
            if (parent == null || GalleryHelper.IsRootAlbum(parent))   //create album from root
                album.PathFromRoot = album.Name;
            else
                album.PathFromRoot = string.Concat(parent.PathFromRoot, Path.DirectorySeparatorChar, album.Name);
            string path = GalleryHelper.GetPhysicalPath(album.PathFromRoot);
            if (Directory.Exists(path))
            {
                GalleryHelper.LastErrorDetail = "The directory [" + path + "] is existed!";
                return false;
            }
            else
                Directory.CreateDirectory(path);
            _isDirty = true;
            return true;
        }

        /// <summary>
        /// Deletes the album.
        /// </summary>
        /// <param name="album">The album.</param>
        public override void DeleteAlbum(GalleryAlbum album)
        {
            string path = GalleryHelper.GetPhysicalPath(album.PathFromRoot);
            if (Directory.Exists(path)) Directory.Delete(path, true);
            _isDirty = true;
        }

        /// <summary>
        /// Updates the album.
        /// </summary>
        /// <param name="album">The album.</param>
        public override void UpdateAlbum(GalleryAlbum album)
        {
            string pathFromRoot = album.PathFromRoot;
            //We update only Name and LastModifiedDate
            string path = GalleryHelper.GetPhysicalPath(pathFromRoot);
            int pos = path.LastIndexOf(Path.DirectorySeparatorChar);
            pathFromRoot = string.Concat(pathFromRoot.Substring(0, pos + 1), album.Name);
            Directory.Move(GalleryHelper.GetPhysicalPath(album.PathFromRoot), GalleryHelper.GetPhysicalPath(pathFromRoot));
            album.PathFromRoot = pathFromRoot;
            _isDirty = true;
        }

        /// <summary>
        /// Gets the child albums.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override GalleryAlbum[] GetChildAlbums(GalleryAlbum album)
        {
            string path = GalleryHelper.GetPhysicalPath(album.PathFromRoot);
            DirectoryInfo dir = new DirectoryInfo(path);
            List<GalleryAlbum> albums = new List<GalleryAlbum>();
            if (dir.Exists)
            {
                DirectoryInfo[] subDirs = dir.GetDirectories();
                string rootPath = GalleryHelper.GetPhysicalPath();
                foreach (DirectoryInfo subDir in subDirs)
                {
                    GalleryAlbum item = new GalleryAlbum();
                    item.Name = subDir.Name;
                    item.PathFromRoot = subDir.FullName.Substring(rootPath.Length);
                    item.CreatedDate = subDir.CreationTimeUtc;
                    item.LastModifiedDate = subDir.LastWriteTimeUtc;
                    albums.Add(item);
                }
            }
            return albums.ToArray();
        }

        /// <summary>
        /// Determines whether [is valid gallery item] [the specified file].
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns>
        /// 	<c>true</c> if [is valid gallery item] [the specified file]; otherwise, <c>false</c>.
        /// </returns>
        protected virtual bool IsValidGalleryItem(FileInfo file)
        {
            return true;
        }

        /// <summary>
        /// Gets the gallery items.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override GalleryItem[] GetGalleryItems(GalleryAlbum album)
        {
            DirectoryInfo dir = GetAlbumDirectory(album);
            FileInfo[] files = dir.GetFiles();
            List<GalleryItem> items = new List<GalleryItem>();
            string rootPath = GalleryHelper.GetPhysicalPath();
            foreach (FileInfo file in files)
            {
                if (this.IsValidGalleryItem(file))
                {
                    GalleryItem item = GetGalleryItemFromFile(file, rootPath);
                    items.Add(item);
                }
            }
            return items.ToArray();
        }

        /// <summary>
        /// Gets the gallery item from file.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <param name="rootPath">The root path.</param>
        /// <returns></returns>
        private GalleryItem GetGalleryItemFromFile(FileInfo file, string rootPath)
        {
            if (file == null || !file.Exists) return null;
            GalleryItem item = new GalleryItem();
            item.Name = Path.GetFileNameWithoutExtension(file.Name);
            item.Description = item.Name;
            item.CreatedDate = file.CreationTimeUtc;
            item.LastModifedDate = file.LastWriteTimeUtc;
            item.PathFromRoot = file.FullName.Substring(rootPath.Length);
            item.Type = DetectGalleryItemType(file.Extension.Substring(1));
            item.Size = (int)file.Length;
            return item;
        }

        private GalleryItem GetGalleryItemFromFile(FileInfo file)
        {
            return GetGalleryItemFromFile(HttpContext.Current, file);
        }

        /// <summary>
        /// Gets the gallery item from file.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns></returns>
        private GalleryItem GetGalleryItemFromFile(HttpContext context, FileInfo file)
        {
            string rootPath = GalleryHelper.GetPhysicalPath();
            return GetGalleryItemFromFile(file, rootPath);
        }

        /// <summary>
        /// Gets the paged gallery items.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="order">The order.</param>
        /// <param name="ascending">if set to <c>true</c> [ascending].</param>
        /// <param name="itemsCount">The items count.</param>
        /// <returns></returns>
        public override GalleryItem[] GetPagedGalleryItems(GalleryAlbum album, int pageIndex, int pageSize, GalleryOrder order, out int itemsCount)
        {
            GalleryItem[] items = GetGalleryItems(album);
            itemsCount = items.Length;
            IList<GalleryItem> sortedItems = null;
            if (order == GalleryOrder.None) return items;
            else if ((order & GalleryOrder.CreatedDate) == GalleryOrder.CreatedDate ||
                (order & GalleryOrder.LastModifiedDate) == GalleryOrder.LastModifiedDate)
            {
                SortedList<DateTime, GalleryItem> list = new SortedList<DateTime, GalleryItem>(items.Length);
                foreach (GalleryItem item in items)
                {
                    DateTime key = ((order & GalleryOrder.CreatedDate) == GalleryOrder.CreatedDate) ? item.CreatedDate : item.LastModifedDate;
                    //Try to pass over the limitation of SortedList when we have two similar keys
                    while (list.ContainsKey(key))
                        key = key.AddMilliseconds(1);
                    list.Add(key, item);
                }
                sortedItems = list.Values;
            }
            else if ((order & GalleryOrder.Vote) == GalleryOrder.Vote)
            {
                SortedList<float, GalleryItem> list = new SortedList<float, GalleryItem>(items.Length);
                foreach (GalleryItem item in items) list.Add(item.Vote, item);
                sortedItems = list.Values;
            }
            else if ((order & GalleryOrder.Name) == GalleryOrder.Name)
            {
                SortedList<string, GalleryItem> list = new SortedList<string, GalleryItem>(items.Length);
                foreach (GalleryItem item in items) list.Add(Path.GetFileName(item.PathFromRoot), item);
                sortedItems = list.Values;
            }
            bool desc = ((order & GalleryOrder.Deasscending) == GalleryOrder.Deasscending);
            return GetPage(sortedItems, pageIndex, pageSize, desc);
        }

        /// <summary>
        /// Gets the gallery items count.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override int GetGalleryItemsCount(GalleryAlbum album)
        {
            string path = GalleryHelper.GetPhysicalPath(album.PathFromRoot);
            DirectoryInfo dir = new DirectoryInfo(path);
            FileInfo[] files = dir.GetFiles();
            int count = files.Length;
            foreach (FileInfo file in files)
            {
                if (!this.IsValidGalleryItem(file))
                    count--;
            }
            return count;
        }

        /// <summary>
        /// Gets the page.
        /// </summary>
        /// <param name="items">The items.</param>
        /// <param name="pageIndex">Index of the page.</param>
        /// <param name="pageSize">Size of the page.</param>
        /// <returns></returns>
        private GalleryItem[] GetPage(IList<GalleryItem> items, int pageIndex, int pageSize, bool desc)
        {
            if (items.Count == 0) return null;
            List<GalleryItem> list = new List<GalleryItem>();
            if (desc)
            {
                int start = items.Count - pageIndex * pageSize;
                int end = start + pageSize - 1;
                if (start < 0)
                    start = 0;
                for (int i = end; i >= start; i--)
                {
                    list.Add(items[i]);
                }
            }
            else
            {
                int end = pageIndex * pageSize;
                int start = end - pageSize;
                int length = items.Count;
                while (start < length && start < end) list.Add(items[start++]);
            }
            return list.ToArray();
        }

        /// <summary>
        /// Gets the gallery album info.
        /// </summary>
        /// <param name="album">The album.</param>
        public override void GetGalleryAlbumInfo(GalleryAlbum album)
        {
            string path = GalleryHelper.GetPhysicalPath(album.PathFromRoot);
            DirectoryInfo dir = new DirectoryInfo(path);
            album.Name = Path.GetFileName(path);
            album.CreatedDate = dir.CreationTimeUtc;
            album.LastModifiedDate = dir.LastWriteTimeUtc;
        }

        /// <summary>
        /// Gets the gallery album info.
        /// </summary>
        /// <param name="albumID">The album ID.</param>
        /// <returns></returns>
        public override GalleryAlbum GetGalleryAlbumInfo(string albumID)
        {
            GalleryAlbum album = new GalleryAlbum();
            album.PathFromRoot = albumID;
            GetGalleryAlbumInfo(album);
            return album;
        }

        /// <summary>
        /// Sets the album ID.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <param name="id">The id.</param>
        public override void SetAlbumID(GalleryAlbum album, object id)
        {
            if (id is string)
                album.PathFromRoot = (string)id;
            else
                throw new ArgumentException("Invalid ID");
        }

        /// <summary>
        /// Resolves the album link.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override string ResolveAlbumLink(GalleryAlbum album)
        {
			string securePath = SecureUrl.EncryptUrl(album.PathFromRoot);
			if (string.IsNullOrEmpty(securePath))
				return string.Empty;
			else
				return "?" + Gallery.GALLERY_ALBUM_ID + "=" + securePath;
		}

        /// <summary>
        /// Resolves the album thumbnail.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override string ResolveAlbumThumbnail(GalleryAlbum album)
        {
            int itemCount = GetGalleryItemsCount(album);
            return string.Concat(GalleryHelper.ThumbnailHandlerName, "?", GalleryHelper.THUMBNAIL_MODE, "=", GalleryHelper.ThumbnailModes.Album,
                "&", Gallery.GALLERY_ALBUM_ID, "=", HttpUtility.UrlEncode(album.PathFromRoot),
                "&", Gallery.GALLERY_ITEM_COUNT, "=", itemCount.ToString());
        }

        /// <summary>
        /// Resolves the item download.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override string ResolveItemDownload(GalleryItem item)
        {
            if (item == null) return string.Empty;

            StringBuilder sb = new StringBuilder();
            sb.Append(GalleryHelper.ThumbnailHandlerName);
            sb.Append("?");
            sb.Append(GalleryHelper.THUMBNAIL_MODE);
            sb.Append('=');
            sb.Append(GalleryHelper.ThumbnailModes.Download);
            //sb.Append('&');
            //sb.Append(GalleryHelper.THUMBNAIL_IMAGETYPE);
            //sb.Append('=');
            //sb.Append(BbqFramework.Drawing.CodecInfos.JPEG.CodecName);
            sb.Append('&');
            sb.Append(Gallery.GALLERY_ITEM_ID);
            sb.Append('=');
            sb.Append(Gallery.GalleryProvider.ResolveItemIdentity(item));

            return sb.ToString();
        }

        /// <summary>
        /// Resolves the item link.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override string ResolveItemLink(GalleryItem item)
        {
			string realPath = string.Concat(GalleryHelper.GalleryRootPath.Replace("~", ""), item.PathFromRoot);
			string securePath = SecureUrl.EncryptUrl(realPath);
			return "BbqSecureUrlHandler.ashx?" + securePath;
        }

        /// <summary>
        /// Resolves the item thumbnail.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override string ResolveItemThumbnail(GalleryItem item)
        {
            if (item == null) return string.Empty;

            StringBuilder sb = new StringBuilder();
            sb.Append(GalleryHelper.ThumbnailHandlerName);
            sb.Append("?");
            sb.Append(GalleryHelper.THUMBNAIL_MODE);
            sb.Append('=');
            switch (item.Type)
            {
                case GalleryItemType.Picture:
                    sb.Append(GalleryHelper.ThumbnailModes.Item);
                    break;
                case GalleryItemType.Archives:
                    sb.Append(GalleryHelper.ThumbnailModes.Download);
                    break;
            }
            //sb.Append('&');
            //sb.Append(GalleryHelper.THUMBNAIL_IMAGETYPE);
            //sb.Append('=');
            //sb.Append(BbqFramework.Drawing.CodecInfos.JPEG.CodecName);
            sb.Append('&');
            sb.Append(Gallery.GALLERY_ITEM_ID);
            sb.Append('=');
            sb.Append(Gallery.GalleryProvider.ResolveItemIdentity(item));

            return sb.ToString();
        }

        /// <summary>
        /// Creates the gallery item.
        /// </summary>
        /// <param name="parentAlbum">The parent album.</param>
        /// <param name="item">The item.</param>
        /// <param name="fileUpload">The file upload.</param>
        /// <param name="isZipFile">if set to <c>true</c> [is zip file].</param>
        /// <returns></returns>
        public override bool CreateGalleryItem(GalleryAlbum parentAlbum, GalleryItem item, FileUpload fileUpload, bool isZipFile)
        {
            if (isZipFile)
            {
                //get directory of album
                string path = GalleryHelper.GetPhysicalPath(string.Concat(parentAlbum.PathFromRoot, Path.DirectorySeparatorChar));
                using (ZipInputStream zipInput = new ZipInputStream(fileUpload.FileContent))
                {
                    const int bufferSize = 8192;
                    ZipEntry zipEntry = null;
                    StringBuilder sbError = new StringBuilder();
                    while ((zipEntry = zipInput.GetNextEntry()) != null)
                    {
                        //We will add all items in the same album. So, we have to split directory name of zip entry
                        string filename = Path.GetFileName(zipEntry.Name);
                        string saveFileName = string.Concat(path, filename);
                        if (File.Exists(saveFileName))
                        {
                            GalleryHelper.LastErrorDetail = string.Concat("File [", saveFileName, "] is existed!");
                            return false;
                        }
                        FileStream streamWriter = null;
                        try
                        {
                            streamWriter = File.Create(saveFileName);
                            byte[] buffer = new byte[bufferSize];
                            int size = 0;
                            while ((size = zipInput.Read(buffer, 0, bufferSize)) > 0)
                            {
                                streamWriter.Write(buffer, 0, size);
                            }
                            streamWriter.Close();
                        }
                        catch (IOException ioEx)
                        {
                            if(streamWriter!=null)
                            {
                                streamWriter.Close();
                                File.Delete(saveFileName);
                            }
                            sbError.Append("IO: ");
                            sbError.AppendLine(ioEx.Message);
                        }
                        catch (ZipException zipEx)
                        {
                            if (streamWriter != null)
                            {
                                streamWriter.Close();
                                File.Delete(saveFileName);
                            }
                            sbError.Append("Zip: ");
                            sbError.AppendLine(zipEx.Message);
                        }
                    }
                    zipInput.Close();
                    return (GalleryHelper.LastErrorDetail = sbError.ToString()).Length == 0;
                }
            }
            else return CreateGalleryItem(parentAlbum, item, fileUpload);
        }

        /// <summary>
        /// Creates the gallery item.
        /// </summary>
        /// <param name="item">The item.</param>
        public override bool CreateGalleryItem(GalleryAlbum parentAlbum, GalleryItem item, FileUpload fileUpload)
        {
            string path;
            
            if (string.IsNullOrEmpty(item.Name))
                path = GalleryHelper.GetPhysicalPath(string.Concat(parentAlbum.PathFromRoot, Path.DirectorySeparatorChar, Path.GetFileName(fileUpload.FileName)));
            else
                path = GalleryHelper.GetPhysicalPath(string.Concat(parentAlbum.PathFromRoot, Path.DirectorySeparatorChar, item.Name, Path.GetExtension(fileUpload.FileName)));
            if (File.Exists(path))
            {
                GalleryHelper.LastErrorDetail = string.Concat("File [", path, "] is existed!");
                return false;
            }
            else
            {
                try
                {
                    fileUpload.SaveAs(path);
                    return true;
                }
                catch (IOException ioEx)
                {
                    GalleryHelper.LastErrorDetail = ioEx.Message;
                    return false;
                }
            }
        }

        /// <summary>
        /// Deletes the gallery item.
        /// </summary>
        /// <param name="item">The item.</param>
        public override void DeleteGalleryItem(GalleryItem item)
        {
            string path = GalleryHelper.GetPhysicalPath(item.PathFromRoot);
            if (File.Exists(path))
            {
                try
                {
                    File.Delete(path);
                }
                catch (Exception ex)
                {
                    GalleryHelper.LastErrorDetail = ex.Message;
                }
            }
        }

        /// <summary>
        /// Gets the next gallery item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override GalleryItem GetNextGalleryItem(GalleryItem item)
        {
            throw new Exception("This method has not been implemented.");
        }

        /// <summary>
        /// Gets the previous gallery item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override GalleryItem GetPreviousGalleryItem(GalleryItem item)
        {
            throw new Exception("This method has not been implemented.");
        }

        /// <summary>
        /// Gets the gallery item info.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override GalleryItem GetGalleryItemInfo(GalleryItem item)
        {
			return GetGalleryItemInfo(item.PathFromRoot);
        }

        /// <summary>
        /// Gets the gallery item info.
        /// </summary>
        /// <param name="itemID">The item ID.</param>
        /// <returns></returns>
        public override GalleryItem GetGalleryItemInfo(string itemID)
        {
            GalleryItem item = this.GetGalleryItemFromFile(new FileInfo(GalleryHelper.GetPhysicalPath(itemID)));
            item.PathFromRoot = itemID;
            return item;
        }

		/// <summary>
		/// Changes the name of the gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="newName">The new name.</param>
		public override void UpdateGalleryItem(GalleryItem item, GalleryItem newItem)
		{
			if (item.Name == newItem.Name)
				return;
			FileInfo fInfo = new FileInfo(GalleryHelper.GetPhysicalPath(item.PathFromRoot));
			string extension = Path.GetExtension(item.PathFromRoot);
			string newPath = Path.GetDirectoryName(item.PathFromRoot) + Path.DirectorySeparatorChar + newItem.Name + extension;
			fInfo.MoveTo(GalleryHelper.GetPhysicalPath(newPath));
			newItem.LastModifedDate = DateTime.Now;
			newItem.PathFromRoot = newPath;
		}

		/// <summary>
		/// Changes the name of the gallery item.
		/// </summary>
		/// <param name="item">The item.</param>
		/// <param name="newName">The new name.</param>
		public override void UpdateGalleryAlbum(GalleryAlbum album, GalleryAlbum newAlbum)
		{
			if (album.Name == newAlbum.Name)
				return;
			DirectoryInfo dInfo = new DirectoryInfo(GalleryHelper.GetPhysicalPath(album.PathFromRoot));
			string newPath = Path.GetDirectoryName(album.PathFromRoot) + Path.DirectorySeparatorChar + newAlbum.Name;
			dInfo.MoveTo(GalleryHelper.GetPhysicalPath(newPath));
			newAlbum.PathFromRoot = newPath;
			newAlbum.LastModifiedDate = DateTime.Now;
		}

		/// <summary>
        /// Gets the highlight item.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override GalleryItem GetHighlightItem(GalleryAlbum album)
        {
            DirectoryInfo dir = GetAlbumDirectory(album);
            FileInfo[] files = dir.GetFiles();
            //Find the latest file
            DateTime date = DateTime.MinValue;
            FileInfo highlightFile  = null;
            if (files == null || files.Length == 0) //try to find in sub folders
            {
                GalleryAlbum[] albums = GetChildAlbums(album);
                foreach (GalleryAlbum cAlbum in albums)
                {
                    cAlbum.AttachHttpContext(album.HttpContext);
                    GalleryItem item = GetHighlightItem(cAlbum);
                    cAlbum.DetachHttpContext();
                    if (item != null)
                        return item;
                }
            }
            else
            {
                foreach (FileInfo file in files)
                {
                    DateTime compareDate = file.LastWriteTime > file.CreationTime ? file.LastWriteTime : file.CreationTime;
                    if (compareDate > date)
                    {
                        if (DetectGalleryItemType(file.Extension.Substring(1)) == GalleryItemType.Picture)
                        {
                            date = compareDate;
                            highlightFile = file;
                        }
                    }
                }
            }
            return GetGalleryItemFromFile(album.HttpContext??HttpContext.Current, highlightFile);
        }

        /// <summary>
        /// Sets the highlight item.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <param name="item">The item.</param>
        public override void SetHighlightItem(GalleryItem item)
        {
            string path = GalleryHelper.GetPhysicalPath(item.PathFromRoot);
            FileInfo file = new FileInfo(path);
            file.LastWriteTime = DateTime.Now;
        }

        /// <summary>
        /// Resolves the item identity.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public override string ResolveItemIdentity(GalleryItem item)
        {
            return SecureUrl.EncryptUrl(item.PathFromRoot);
        }

		/// <summary>
		/// Some provider can encrypt Item ID. This function will return the actual item identity
		/// </summary>
		/// <param name="itemID">The item ID.</param>
		/// <returns></returns>
		public override string GetActualItemIdentity(string itemID)
		{
			return SecureUrl.DecryptUrl(itemID);
		}

        /// <summary>
        /// Resolves the album identity.
        /// </summary>
        /// <param name="album">The album.</param>
        /// <returns></returns>
        public override string ResolveAlbumIdentity(GalleryAlbum album)
        {
			return SecureUrl.EncryptUrl(album.PathFromRoot);
        }

		/// <summary>
		/// Gets the actual album identity.
		/// </summary>
		/// <param name="albumID">The album ID.</param>
		/// <returns></returns>
		public override string GetActualAlbumIdentity(string albumID)
		{
			return SecureUrl.DecryptUrl(albumID);
		}

        public override bool CreateGalleryItem(GalleryAlbum parentAlbum, GalleryItem item)
        {
            throw new NotImplementedException();
        }
    }
}
